use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::{Instant, Duration};
use serde::Serialize;

/// 函数调用指标
#[derive(Debug, Clone, Serialize)]
pub struct FunctionMetrics {
    /// 总调用次数
    pub call_count: u64,
    /// 总执行时间（毫秒）
    pub total_time_ms: u64,
    /// 平均执行时间（毫秒）
    pub avg_time_ms: f64,
    /// 最短执行时间（毫秒）
    pub min_time_ms: u64,
    /// 最长执行时间（毫秒）
    pub max_time_ms: u64,
    /// 错误次数
    pub error_count: u64,
}

impl FunctionMetrics {
    fn new() -> Self {
        Self {
            call_count: 0,
            total_time_ms: 0,
            avg_time_ms: 0.0,
            min_time_ms: u64::MAX,
            max_time_ms: 0,
            error_count: 0,
        }
    }
    
    fn update(&mut self, duration_ms: u64) {
        self.call_count += 1;
        self.total_time_ms += duration_ms;
        self.min_time_ms = self.min_time_ms.min(duration_ms);
        self.max_time_ms = self.max_time_ms.max(duration_ms);
        self.avg_time_ms = self.total_time_ms as f64 / self.call_count as f64;
    }
    
    fn record_error(&mut self) {
        self.error_count += 1;
    }
}

/// 调用跟踪器
pub struct CallTracker {
    function_name: String,
    start_time: Instant,
    metrics_collector: Arc<Mutex<MetricsCollector>>,
}

impl CallTracker {
    fn new(function_name: &str, metrics_collector: Arc<Mutex<MetricsCollector>>) -> Self {
        Self {
            function_name: function_name.to_string(),
            start_time: Instant::now(),
            metrics_collector,
        }
    }
}

impl Drop for CallTracker {
    fn drop(&mut self) {
        let duration = self.start_time.elapsed();
        let duration_ms = duration.as_millis() as u64;
        
        let mut collector = self.metrics_collector.lock().unwrap();
        collector.record_call(&self.function_name, duration_ms);
    }
}

/// 性能指标收集器
#[derive(Clone)]
pub struct MetricsCollector {
    metrics: Arc<Mutex<HashMap<String, FunctionMetrics>>>,
}

impl MetricsCollector {
    pub fn new() -> Self {
        Self {
            metrics: Arc::new(Mutex::new(HashMap::new())),
        }
    }
    
    /// 开始跟踪函数调用
    pub fn start_call(&self, function_name: &str) -> CallTracker {
        CallTracker::new(function_name, Arc::new(Mutex::new(self.clone())))
    }
    
    /// 记录函数调用
    pub fn record_call(&mut self, function_name: &str, duration_ms: u64) {
        let mut metrics = self.metrics.lock().unwrap();
        let function_metrics = metrics
            .entry(function_name.to_string())
            .or_insert_with(FunctionMetrics::new);
            
        function_metrics.update(duration_ms);
    }
    
    /// 记录函数调用错误
    pub fn record_error(&self, function_name: &str) {
        let mut metrics = self.metrics.lock().unwrap();
        let function_metrics = metrics
            .entry(function_name.to_string())
            .or_insert_with(FunctionMetrics::new);
            
        function_metrics.record_error();
    }
    
    /// 获取性能指标报告
    pub fn get_metrics_report(&self) -> HashMap<String, FunctionMetrics> {
        let metrics = self.metrics.lock().unwrap();
        metrics.clone()
    }
    
    /// 重置所有指标
    pub fn reset(&self) {
        let mut metrics = self.metrics.lock().unwrap();
        metrics.clear();
    }
}

impl Default for MetricsCollector {
    fn default() -> Self {
        Self::new()
    }
}